<!DOCTYPE html>
<html>
<head>
<title>ProFTPD module mod_exec</title>
</head>

<body bgcolor=white>

<hr><br>
<center>
<h2><b>ProFTPD module <code>mod_exec</code></b></h2>
</center>
<hr><br>

This module is contained in the <code>mod_exec.c</code> file for
ProFTPD 1.3.<i>x</i>, found
<a href="http://www.castaglia.org/proftpd/">here</a>, and is not compiled by
default.  Installation instructions are discussed
<a href="#Installation">here</a>.

<p>
The <code>mod_exec</code> module can be used to execute external programs
or scripts at various points in the process of handling FTP commands.  By
conscious design, the core ProFTPD engine does not and will not execute
external programs.  This is a security decision, as it was decided not to allow
ProFTPD to serve as a means of compromising a system or disclosing information
via bugs in external programs or scripts.  Use of this module allows for such
external programs to be executed, and also opens up the server to the
mentioned possibilities of compromise or disclosure via those programs.

<p>
<center>
  <b>YOU HAVE BEEN WARNED</b><br>
  <b>USE AT YOUR OWN RISK</b><br>
</center>

<p>
Please read the <a href="#Usage">usage</a> section to know the other caveats
with this module.

<p>
The most current version of <code>mod_exec</code> is distributed with the
ProFTPD source code.

<h2>Author</h2>
<p>
Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
questions, concerns, or suggestions regarding this module.

<h2>Directives</h2>
<ul>
  <li><a href="#ExecBeforeCommand">ExecBeforeCommand</a>
  <li><a href="#ExecEnable">ExecEnable</a>
  <li><a href="#ExecEngine">ExecEngine</a>
  <li><a href="#ExecEnviron">ExecEnviron</a>
  <li><a href="#ExecLog">ExecLog</a>
  <li><a href="#ExecOnCommand">ExecOnCommand</a>
  <li><a href="#ExecOnConnect">ExecOnConnect</a>
  <li><a href="#ExecOnError">ExecOnError</a>
  <li><a href="#ExecOnEvent">ExecOnEvent</a>
  <li><a href="#ExecOnExit">ExecOnExit</a>
  <li><a href="#ExecOnRestart">ExecOnRestart</a>
  <li><a href="#ExecOptions">ExecOptions</a>
  <li><a href="#ExecTimeout">ExecTimeout</a>
</ul>

<hr>
<h3><a name="ExecBeforeCommand">ExecBeforeCommand</a></h3>
<strong>Syntax:</strong> ExecBeforeCommand <em>cmds path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.8 and later

<p>
The <code>ExecBeforeCommand</code> directive is used to execute the program or
script at <i>path</i> <b>before</b> the handling of any FTP command listed
in <i>cmds</i>, where <i>cmds</i> is a comma-delimited list of FTP commands.
The command groups of the <code>&lt;Limit&gt;</code> directive, such as
READ, WRITE, and ALL, may also be used.  The program will be executed with
the privileges of the logged-in user.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
<b>Important</b>: use of <code>DefaultRoot</code> will cause complications
(to be elaborated upon soon).

<p>
Example:
<pre>
  ExecBeforeCommand RETR /path/to/ftp-prep --file %f
</pre>

<p>
See Also:
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnError">ExecOnError</a>,
  <a href="#ExecOnExit">ExecOnExit</a>,
  <a href="#ExecOnRestart">ExecOnRestart</a>,
  <a href="http://www.proftpd.org/docs/directives/linked/config_ref_Limit.html">&lt;Limit&gt;</a>

<p>
<hr>
<h3><a name="ExecEnable">ExecEnable</a></h3>
<strong>Syntax:</strong> ExecEnable <em>on|off</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code>, <code>.ftpaccess</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.3.6rc1 and later

<p>
The <code>ExecEnable</code> directive can be used to disable the execution
of commands by <code>mod_exec</code> for particular directories or anonymous
logins.

<p>
<hr>
<h3><a name="ExecEngine">ExecEngine</a></h3>
<strong>Syntax:</strong> ExecEngine <em>on|off</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecEngine</code> directive enables or disables the module's
runtime exec engine.  If it is set to <em>off</em> this module will not
manipulate environment variables or execute external scripts.  Use this
directive to disable the module instead of commenting out all
<code>mod_exec</code> directives.

<p>
<hr>
<h3><a name="ExecEnviron">ExecEnviron</a></h3>
<strong>Syntax:</strong> ExecEnviron <em>key value</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecEnviron</code> directive is used to set the environment variables
in the environment created for the script to be executed.  The current
environment is not passed directly to the script; this is to prevent unwanted
information leakage.  The given <i>key</i> parameter will be uppercased,
to follow the convention for environment variable keys.

<p>
The <i>value</i> parameter may be any arbitrary string which may contain
any of the following variables, which will be substituted with the
corresponding value before the script is executed:
<ul>
  <li><b>%A</b> - anonymous login password
  <li><b>%a</b> - client's IP address
  <li><b>%b</b> - bytes transferred
  <li><b>%C</b> - current working directory
  <li><b>%c</b> - connection class
  <li><b>%F</b> - transferred file as seen by client
  <li><b>%f</b> - full transferred file path
  <li><b>%g</b> - name of primary group of local user
  <li><b>%h</b> - client's DNS name
  <li><b>%m</b> - FTP command (e.g. RETR, STOR, etc)
  <li><b>%r</b> - full FTP command
  <li><b>%U</b> - original username sent by client
  <li><b>%u</b> - name of local user
  <li><b>%v</b> - name of server handling session
  <li><b>%w</b> - RNFR path ("whence" a rename comes, <i>i.e.</i> the source path)
</ul>
The <i>value</i> parameter may be also be &quot;-&quot;, which indicates that
the current value of the environment variable of name <i>key</i> should be
used (<i>e.g.</i> PATH).  If there is no environment of name <i>key</i> when
&quot;-&quot; is used, it will be created with a blank string as the value.

<p>
<hr>
<h3><a name="ExecLog">ExecLog</a></h3>
<strong>Syntax:</strong> ExecLog <em>file|&quot;none&quot;</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecLog</code> directive is used to specify a log file for
<code>mod_exec</code> reporting and debugging, and can be done a per-server
basis.  The <em>file</em> parameter must be the full path to the file to use for
logging.  Note that this path must <b>not</b> be to a world-writeable
directory and, unless <code>AllowLogSymlinks</code> is explicitly set to
<em>on</em> (generally a bad idea), the path must <b>not</b> be a symbolic
link.

<p>
If <em>file</em> is &quot;none&quot;, no logging will be done at all; this
setting can be used to override an <code>ExecLog</code> setting inherited from
a <code>&lt;Global&gt;</code> context.

<p>
<hr>
<h3><a name="ExecOnCommand">ExecOnCommand</a></h3>
<strong>Syntax:</strong> ExecOnCommand <em>cmds path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecOnCommand</code> directive is used to execute the program or
script at <i>path</i> <b>after</b> the successful completion of any FTP command
listed in <i>cmds</i>, where <i>cmds</i> is a comma-delimited list of FTP
commands.  The command groups of the <code>&lt;Limit&gt;</code> directive,
such as READ, WRITE, and ALL, may also be used.  The program will be executed
with the privileges of the logged-in user.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
<b>Important</b>: use of <code>DefaultRoot</code> will cause complications
(to be elaborated upon soon).

<p>
Example:
<pre>
  ExecOnCommand APPE,STOR /path/to/ftp-email-script --user %u --file %f
</pre>

<p>
See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnError">ExecOnError</a>,
  <a href="#ExecOnExit">ExecOnExit</a>,
  <A href="#ExecOnRestart">ExecOnRestart</a>,
  <a href="http://www.proftpd.org/docs/directives/linked/config_ref_Limit.html">&lt;Limit&gt;</a>

<p>
<hr>
<h3><a name="ExecOnConnect">ExecOnConnect</a></h3>
<strong>Syntax:</strong> ExecOnConnect <em>path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecOnConnect</code> directive is used to execute the program or
script at <i>path</i> whenever a client connects to the server.  The program
will be executed with the privileges of the contacted server, which are
set via the <code>User</code>/<code>Group</code> directives.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
Example:
<pre>
  ExecOnConnect /path/to/ftp-logger --ip %a --dns %h
</pre>

<p>
See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnError">ExecOnError</a>,
  <a href="#ExecOnExit">ExecOnExit</a>,
  <a href="#ExecOnRestart">ExecOnRestart</a>

<p>
<hr>
<h3><a name="ExecOnError">ExecOnError</a></h3>
<strong>Syntax:</strong> ExecOnError <em>cmds path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecOnError</code> directive is used to execute the program or
script at <i>path</i> if an error occurs while processing any FTP command listed
in <i>cmds</i>, where <i>cmds</i> is a comma-delimited list of FTP commands.
The command groups of the <code>&lt;Limit&gt;</code> directive, such as
READ, WRITE, and ALL, may also be used.  The program will be executed with
the privileges of the logged-in user.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
<b>Important</b>: use of <code>DefaultRoot</code> will cause complications
(to be elaborated upon soon).

<p>
Example:
<pre>
  ExecOnError APPE,STOR /path/to/ftp-cleanup-script --user %u --file %f
</pre>

See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnExit">ExecOnExit</a>,
  <a href="#ExecOnRestart">ExecOnRestart</a>,
  <a href="http://www.proftpd.org/docs/directives/linked/config_ref_Limit.html">&lt;Limit&gt;</a>

<p>
<hr>
<h3><a name="ExecOnEvent">ExecOnEvent</a></h3>
<strong>Syntax:</strong> ExecOnEvent <em>event[*|~] path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.10rc1 and later

<p>
The <code>ExecOnEvent</code> directive is used to execute the program or
script at <i>path</i> when the given <em>event</em> occurs.  The program will
be executed with the privileges of the server (set via the <code>User</code>
and <code>Group</code> directives in the <code>proftpd.conf</code>file),
unless the <em>event</em> name is followed either by a &quot;*&quot; <em>or</em>
a &quot;~&quot; character.

<p>
If the <em>event</em> name is followed by a &quot;*&quot;, the program will be
executed with root privileges.  <b>Note</b>: this feature should be used
<b>very carefully</b>.  It allows scripts to modify things like firewall
rules, but should be used <b>only</b> for such sensitive tasks.

<p>
If, on the other hand, the <em>eevent</em> name is followed by a &quot;~&quot;,
the program will be executed with the privileges of the logged-in user.
<b>Note</b>: support for this feature first appeared in
<code>proftpd-1.3.5rc4</code>.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
Presently only two specific events are supported: <code>MaxConnectionRate</code>
and <code>MaxInstances</code>.  These events happen when ever the limit
configured by these configuration directives is reached.

<p>
This directive may be used several times to configure multiple programs
to be invoked when <em>event</em> occurs.

<p>
<b>Important</b>: use of <code>DefaultRoot</code> will cause complications
(to be elaborated upon soon).

<p>
Example:
<pre>
  ExecOnEvent MaxConnectionRate* /path/to/ftp-firewall-script --ip %a
</pre>

See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnExit">ExecOnExit</a>,
  <a href="#ExecOnRestart">ExecOnRestart</a>

<p>
<hr>
<h3><a name="ExecOnExit">ExecOnExit</a></h3>
<strong>Syntax:</strong> ExecOnExit <em>path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.8 and later

<p>
The <code>ExecOnExit</code> directive is used to execute the program or
script at <i>path</i> whenever a client disconnects to the server.  The program
will be executed with the privileges of the contacted server, which are
set via the <code>User</code>/<code>Group</code> directives.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
Example:
<pre>
  ExecOnExit /path/to/ftp-logger --ip %a --dns %h
</pre>

<p>
See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnError">ExecOnError</a>,
  <a href="#ExecOnRestart">ExecOnRestart</a>

<p>
<hr>
<h3><a name="ExecOnRestart">ExecOnRestart</a></h3>
<strong>Syntax:</strong> ExecOnRestart <em>path [arg1 arg2 ...]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code>, <code>&lt;Anonymous&gt;</code>, <code>&lt;Directory&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.5rc2 and later

<p>
The <code>ExecOnRestart</code> directive is used to execute the program or
script at <i>path</i> whenever the server receives a <code>SIGHUP</code>
signal.  The program will be executed with the privileges of the contacted
server, which are set via the <code>User</code>/<code>Group</code> directives.

<p>
Any number of arbitrary arguments may be configured to pass to the script.
In addition, the variables supported by the <code>ExecEnviron</code> directive
may also be used in the script argument list.

<p>
Example:
<pre>
  ExecOnRestart /path/to/ftp-counter-reset
</pre>

See Also:
  <a href="#ExecBeforeCommand">ExecBeforeCommand</a>,
  <a href="#ExecEnviron">ExecEnviron</a>,
  <a href="#ExecOnCommand">ExecOnCommand</a>,
  <a href="#ExecOnConnect">ExecOnConnect</a>,
  <a href="#ExecOnError">ExecOnError</a>,
  <a href="#ExecOnExit">ExecOnExit</a>

<p>
<hr>
<h3><a name="ExecOptions">ExecOptions</a></h3>
<strong>Syntax:</strong> ExecOptions <em>opt1 ...</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.9rc2 and later

<p>
The <code>ExecOptions</code> directive is used to configure various optional
behavior of <code>mod_exec</code>.

<p>
Example:
<pre>
  ExecOptions logStderr sendStdout
</pre>

<p>
The currently implemented options are:
<ul>
  <li><code>logStderr</code><br>
    <p>When executing commands, <code>mod_exec</code> usually ignore any
    <code>stderr</code> output of the command.  If this option is enabled,
    <code>mod_exec</code> will monitor for and log any <code>stderr</code>
    from the executed command to the <code>ExecLog</code>.

  <p>
  <li><code>logStdout</code><br>
    <p>When executing commands, <code>mod_exec</code> usually ignore any
    <code>stdout</code> output of the command.  If this option is enabled,
    <code>mod_exec</code> will monitor for and log any <code>stdout</code>
    from the executed command to the <code>ExecLog</code>.

  <p>
  <li><code>sendStdout</code><br>
    <p>If this option is enabled, <code>mod_exec</code> will attempt to
    send any <code>stdout</code> output from the executed command to the
    connected client.  Note that this only works for commands that are
    executed via <code>ExecOnCommand</code> or <code>ExecOnConnect</code>.
    <p>
    <b>Note</b> this this option should <b>not</b> be used for SSH2/SFTP/SCP
    sessions, as it will only cause connection problems for SSH2/SFTP/SCP
    clients.

  <p>
  <li><code>useStdin</code><br>
    <p>If this option is enabled, <code>mod_exec</code> will <b>not</b>
    send arguments to the command being executed using the command line;
    instead, those arguments will written to the <code>stdin</code> stream.
    Each command-line argument will be written as a newline-terminated
    string to <code>stdin</code>; the end of arguments is indicated by
    writing the period ('.') character on a line by itself (again, terminated
    with a newline).

    <p>
    For example, a Perl script reading its arguments from <code>stdin</code>
    would use something like:
<pre>
    while (my $line = &lt;STDIN&gt;) {
      chomp($line);

      if ($line eq ".") {
        last;
      }

      # Handle $line appropriately here
    }
</pre>
    The advantange of using this <code>useStdin</code> option is that some
    systems have tools (<i>e.g.</i> <code>ps</code>) which will show the
    command-line arguments to commands being executed.  For the security
    conscious, using <code>stdin</code> to pass arguments is less visible
    to other users of the system.
</ul>

<p>
<hr>
<h3><a name="ExecTimeout">ExecTimeout</a></h3>
<strong>Syntax:</strong> ExecTimeout <em>seconds</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_exec<br>
<strong>Compatibility:</strong> 1.2.9rc2 and later

<p>
The <code>ExecTimeout</code> directive is used to set a limit on how long
the executed commands can run.  Processes that exceed the configured timeout
will first be sent SIGTERM, to allow them to cleanly shutdown.  If the process
is still around, it will then be sent SIGKILL, which cannot be ignored. A
value of zero configures an infinite timeout (not recommended).

<p>
<hr>
<h2><a name="Usage">Usage</a></h2>
Example configuration:
<pre>
  &lt;IfModule mod_exec.c&gt;
    ExecEngine on
    ExecLog /var/log/ftpd/exec.log
    ExecOnConnect /path/to/script
  &lt;/IfModule&gt;
</pre>

<p>
This module will not work properly for <code>&lt;Anonymous&gt;</code> logins,
or for logins that are affected by <code>DefaultRoot</code>.  These directives
use the <code>chroot(2)</code> system call, which wreaks havoc when it
comes to scripts.  The path to script/shell interpreters often assume a certain
location that is no longer valid within a chroot.  In addition, most modern
operating systems use dynamically loaded libraries (<code>.so</code>
libraries) for many binaries, including script/shell interpreters.  The
location of these libraries, when they come to be loaded, are also assumed;
those assumptions break within a chroot.  Perl, in particular, is so
wrought with filesystem location assumptions that it's almost impossible
to get a Perl script to work within a chroot, short of installing Perl
itself into the chroot environment.

<p>
In short, this module is probably not what you want.  And, try as I might,
I cannot convince users that this module is not what they want.  Therefore,
I'll let you try to use this module yourself, and you can prove to yourself
that it probably won't do what you want.

<p>
As an alternative to <code>mod_exec</code> for executing arbitrary
scripts/commands based on FTP command issued, file uploaded/downloaded,
<i>etc</i>, I recommend using a logging FIFO-based approach, similar to
what is illustrated <a href="../howto/Logging.html">here</a>.  This approach
allows for any script you wish, and is not subject to the restrictions of a
chroot, meaning that you can use <code>DefaultRoot</code> and still have
arbitrary scripts executed.  If requested, I can provide help in writing a
FIFO reader to execute the necessary scripts.

<p>
<hr>
<h2><a name="Installation">Installation</a></h2>
The <code>mod_exec</code> module is distributed with ProFTPD.  Follow the
usual steps for using third-party modules in ProFTPD:
<pre>
  $ ./configure --with-modules=mod_exec
</pre>
To build <code>mod_exec</code> as a DSO module:
<pre>
  $ ./configure --enable-dso --with-shared=mod_exec
</pre>
Then follow the usual steps:
<pre>
  $ make
  $ make install
</pre>

<p>
Alternatively, if your <code>proftpd</code> was compiled with DSO support, you
can use the <code>prxs</code> tool to build <code>mod_exec</code> as a shared
module:
<pre>
  $ prxs -c -i -d mod_exec.c
</pre>

<p><a name="FAQ"></a>
<b>Frequently Asked Questions</b><br>
<font color=red>Question</font>: Why do <code>%U/%u</code> not work properly with <code>ExecOnConnect</code>?<br>
<font color=blue>Answer</font>: Both <code>%U</code> and <code>%u</code> will
be empty on <code>ExecOnConnect</code> because, at that point, the client has
done a TCP connect to the server, but has not sent any sort of information
(including user name).  Which means that <code>mod_exec</code> does not have
a user name to use at connect time.

<p>
One way to work around this limitation is to use a different trigger,
<i>e.g.</i>:
<pre>
  ExecOnCommand PASS ...
</pre>
By the time the client sends the <code>USER</code> and <code>PASS</code>
commands, the server will have the necessary user information to populate
the <code>%U/%u</code> variables.

<p>
<hr>
<font size=2><b><i>
&copy; Copyright 2000-2017 TJ Saunders<br>
 All Rights Reserved<br>
</i></b></font>
<hr>

</body>
</html>

